package com.youhome.wechat.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.youhome.common.response.Result;
import com.youhome.common.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
public class AuthTokenFilter extends AbstractAuthenticationProcessingFilter {

    public AuthTokenFilter(RequestMatcher matcher) {
        super(matcher);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        String authToken = request.getHeader("Authorization");
        log.error("start to check token:{} *************", authToken);
        if (authToken == null || !authToken.startsWith("Bearer ")) {
            throw new AuthenticationCredentialsNotFoundException("未提供Access Token");
        }
        String token = authToken.substring("Bearer ".length());
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(token, null);
        return getAuthenticationManager().authenticate(authentication);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                            Authentication auth) throws IOException, ServletException {
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(auth);
        SecurityContextHolder.setContext(context);
        chain.doFilter(request, response);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                              AuthenticationException authException) throws IOException, ServletException {
        SecurityContextHolder.clearContext();
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        String message;
        if (authException.getCause() != null) {
            message = authException.getCause().getMessage();
        } else {
            message = authException.getMessage();
        }
        System.err.println(message);
//        BaseResponse baseResponse = new BaseResponse();
//        baseResponse.setStatusCode(IConstants.RESPONSE_STATUS_CODE_FAILED);
//        baseResponse.setStatusMsg(message);

        Result result = new Result(ResultCode.FAIL, message);
        byte[] body = new ObjectMapper().writeValueAsBytes(result);
        response.getOutputStream().write(body);
    }

}